package com.fist.eth.flutter_plugin_eth_wallet.utils

import android.util.Log
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fist.eth.flutter_plugin_eth_wallet.BuildConfig
import org.bitcoinj.crypto.*
import org.bitcoinj.params.MainNetParams
import org.web3j.crypto.*
import java.io.File
import java.io.IOException
import java.security.SecureRandom
import java.text.SimpleDateFormat
import java.util.*


object TokenWalletUtils {
    private val objectMapper = ObjectMapper()
    private val secureRandom = SecureRandom()

    init {
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    @Throws(CipherException::class, IOException::class)
    fun importTokenWallet(mnemonic: String, password: String): TokenWallet {
        val seed = MnemonicUtils.generateSeed(mnemonic, null)
        // 3. 生成根私钥 root private key 树顶点的master key
        val child = getDeterministicKeyBip44BySeed(seed)
        val privateKeyByte = child.privKeyBytes
        //        ECKeyPair privateKey = ECKeyPair.create(sha256(seed));
        //通过私钥生成公私钥对
        val keyPair = ECKeyPair.create(privateKeyByte)
        val walletFile = Wallet.createLight(password, keyPair)
        Log.i("TAG", "generateBip44Wallet: 地址 = " + Keys.toChecksumAddress(walletFile.address))
        return TokenWallet(walletFile, mnemonic, keyPair)
    }

    @Throws(CipherException::class, IOException::class)
    fun generateWalletFile(password: String, ecKeyPair: ECKeyPair, destinationDirectory: File, useFullScrypt: Boolean): String {

        val walletFile: WalletFile = if (useFullScrypt) {
            Wallet.createStandard(password, ecKeyPair)
        } else {
            Wallet.createLight(password, ecKeyPair)
        }

        val fileName = getWalletFileName(walletFile)
        val destination = File(destinationDirectory, fileName)

        objectMapper.writeValue(destination, walletFile)

        return fileName
    }

    private fun getWalletFileName(walletFile: WalletFile): String {
        val dateFormat = SimpleDateFormat("'UTC--'yyyy-MM-dd'T'HH-mm-ss.SSS'--'")
        return dateFormat.format(Date()) + walletFile.address + ".json"
    }


    private fun getDeterministicKeyBip44BySeed(seed: ByteArray): DeterministicKey {
        // 3. 生成根私钥 root private key 树顶点的master key
        val rootPrivateKey = HDKeyDerivation.createMasterPrivateKey(seed)
        if (BuildConfig.DEBUG) {
            // 根私钥进行 priB58编码,得到测试网站上显示的数据
            val params = MainNetParams.get()
            val privateKey = rootPrivateKey.serializePrivB58(params)
            Log.i("TAG", "BIP32 Extended Private Key:$privateKey")
        }
        // 4. 由根私钥生成 第一个HD 钱包
        val dh = DeterministicHierarchy(rootPrivateKey)
        // 5. 定义父路径 H则是加强 imtoken中的eth钱包进过测试发现使用的是此方式生成
        val parentPath = HDUtils.parsePath("M/44H/60H/0H/0")
        // 6. 由父路径,派生出第一个子私钥 "new ChildNumber(0)" 表示第一个 （m/44'/60'/0'/0/0）
        return dh.deriveChild(parentPath, true, true, ChildNumber(0))
    }
}